package initconf

import (
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"go_web_learn/common"
	"os"
)

// var (
//
//	logInfo  *log.Logger
//	logWarn  *log.Logger
//	logError *log.Logger
//	Log      *logrus.Logger // 依赖的日志 上面的是jdk的自带的日志
//
// )
//
// // init()函数会在包被初始化后自动执行，并且在main()函数之前执行，但是需要注意的是init()以及main()函数都是无法被显式调用的。
// // 那么init()是不是最先执行的呢？ 答案是否定的，首先，在他之前会进行全局变量的初始化
//
//	func InitLog() {
//		file, err := os.OpenFile(Conf.LogConfig.FilePath+"/"+Conf.LogConfig.Filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
//		multiWriter := io.MultiWriter(file, os.Stdout)
//		if err != nil {
//			log.Fatalln(err)
//		}
//		logInfo = log.New(multiWriter, "[INFO] - ", log.Ldate|log.Lmicroseconds|log.Llongfile)
//		logWarn = log.New(multiWriter, "[WARN] - ", log.Ldate|log.Lmicroseconds|log.Llongfile)
//		logError = log.New(multiWriter, "[ERROR] - ", log.Ldate|log.Lmicroseconds|log.Llongfile)
//		logrusConf(&multiWriter)
//	}
//
//	func logrusConf(writer *io.Writer) {
//		Log = logrus.New()
//		Log.SetOutput(*writer)
//		switch Conf.LogConfig.Formatter {
//		case "TEXT":
//			Log.SetFormatter(&logrus.TextFormatter{})
//		case "JSON":
//			Log.SetFormatter(&logrus.JSONFormatter{})
//		}
//		switch Conf.LogConfig.Level {
//		case "DEBUG":
//			Log.SetLevel(logrus.DebugLevel)
//		case "INFO":
//			Log.SetLevel(logrus.InfoLevel)
//		case "WARN":
//			Log.SetLevel(logrus.WarnLevel)
//		case "ERROR":
//			Log.SetLevel(logrus.ErrorLevel)
//		}
//	}
//
//	func INFO(data ...any) {
//		// 等于是把参数展开一个一个放进去
//		logInfo.Println(data...)
//	}
//
//	func WARN(data ...any) {
//		// 等于是把参数展开一个一个放进去
//		logWarn.Println(data...)
//	}
//
//	func ERROR(data ...any) {
//		// 等于是把参数展开一个一个放进去
//		logError.Println(data...)
//	}

var Log *zap.Logger

func InitLogger() {
	encoder := zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
		TimeKey:        "ts",
		LevelKey:       "level",
		NameKey:        "logger",
		CallerKey:      "caller",
		MessageKey:     "msg",
		StacktraceKey:  "stacktrace",
		LineEnding:     zapcore.DefaultLineEnding,
		EncodeLevel:    zapcore.CapitalColorLevelEncoder,                       // 彩色 info、ERROR 等
		EncodeTime:     zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000"), // 时间精确到毫秒
		EncodeDuration: zapcore.StringDurationEncoder,
		EncodeCaller:   zapcore.ShortCallerEncoder,
	})

	core := zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel)

	Log = zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
	zap.ReplaceGlobals(Log)
}

func InfoCtx(c *gin.Context, msg string, data ...any) {
	traceIdVal, exists := c.Get(common.TRACE_NO)
	var traceNo string
	if exists {
		traceNo, _ = traceIdVal.(string)
	}
	field := zap.Any("log_data", data)
	var fields []zap.Field
	Log.Info(msg, append(fields, field, zap.String(common.TRACE_NO, traceNo))...)
}

func WarnCtx(c *gin.Context, msg string, data ...any) {
	traceIdVal, exists := c.Get(common.TRACE_NO)
	var traceNo string
	if exists {
		traceNo, _ = traceIdVal.(string)
	}
	field := zap.Any("log_data", data)
	var fields []zap.Field
	Log.Info(msg, append(fields, field, zap.String(common.TRACE_NO, traceNo))...)
}

func ErrorCtx(c *gin.Context, msg string, data ...any) {
	traceIdVal, exists := c.Get(common.TRACE_NO)
	var traceNo string
	if exists {
		traceNo, _ = traceIdVal.(string)
	}
	field := zap.Any("log_data", data)
	var fields []zap.Field
	Log.Info(msg, append(fields, field, zap.String(common.TRACE_NO, traceNo))...)
}

func InfoCtxField(c *gin.Context, msg string, fields ...zap.Field) {
	traceIdVal, exists := c.Get(common.TRACE_NO)
	var traceNo string
	if exists {
		traceNo, _ = traceIdVal.(string)
	}
	Log.Warn(msg, append(fields, zap.String(common.TRACE_NO, traceNo))...)
}

func WarnCtxField(c *gin.Context, msg string, fields ...zap.Field) {
	traceIdVal, exists := c.Get(common.TRACE_NO)
	var traceNo string
	if exists {
		traceNo, _ = traceIdVal.(string)
	}
	Log.Warn(msg, append(fields, zap.String(common.TRACE_NO, traceNo))...)
}

func ErrorCtxField(c *gin.Context, msg string, fields ...zap.Field) {
	traceIdVal, exists := c.Get(common.TRACE_NO)
	var traceNo string
	if exists {
		traceNo, _ = traceIdVal.(string)
	}
	Log.Error(msg, append(fields, zap.String("traceId", traceNo))...)
}
